package com.weixing.mall.pay.channel.ali;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayConstants;
import com.alipay.api.internal.util.AlipaySignature;
import com.google.common.collect.Maps;
import com.weixing.mall.base.constant.DatePattern;
import com.weixing.mall.base.exception.BusinessException;
import com.weixing.mall.pay.INotify;
import com.weixing.mall.pay.NotifyResult;
import com.weixing.mall.pay.properties.AliPayProperties;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * @ClassName AliNotify
 * @Description
 * @Author Small
 * @Date 2019/12/10 19:15
 * @Version 1.0
 **/
@Slf4j
public class AliNotify implements INotify {
    private AliPayProperties payProperties;
    private List<Map<String, Object>> setVoMapList;

    public AliNotify(AliPayProperties payProperties) {
        this.payProperties = payProperties;
    }

    public AliNotify(List<Map<String, Object>> setVoMapList) {
        this.setVoMapList = setVoMapList;
    }

    /**
     * 方法描述: 支付宝支付回调
     * @Author Small
     * @param request
     * @Date 2019/12/10 11:38
     * @return com.weixing.mall.pay.NotifyResult
     */
    @Override
    public NotifyResult doNotify(HttpServletRequest request) {
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }

        // 动态查找这次回调该匹配哪一个配置
        String out_trade_no = params.get("out_trade_no");
        Date now = DateUtil.parse(out_trade_no.substring(0, 14), DatePattern.PURE_DATETIME_PATTERN);
        int size = setVoMapList.size();
        Map<String, Object> paySetMap = null;
        for (int i = 0; i < size; i++) {
            Map<String, Object> stringObjectMap = setVoMapList.get(i);
            Date effectStartTime = (Date) stringObjectMap.get("effectStartTime");
            Date effectEndTime = (Date) stringObjectMap.get("effectEndTime");
            if (now.compareTo(effectStartTime) >= 0 && now.compareTo(effectEndTime) <= 0) {
               paySetMap = stringObjectMap;
                break;
            }
        }
        if (null == paySetMap){
            throw  new BusinessException("支付回调失败，失败原因：找不到相应的支付配置");
        }
        String paramSet = (String) paySetMap.get("paramSet");
        JSONObject jsonObject = JSON.parseObject(paramSet);
        // 验签状态
        boolean verify_result;
        try {
            //计算得出通知验证结果
            verify_result = AlipaySignature.rsaCheckV1(params, jsonObject.getString("alipayPublicKey"),
                    AlipayConstants.CHARSET_UTF8,
                    AlipayConstants.SIGN_TYPE_RSA2);
        } catch (AlipayApiException e) {
            log.warn("支付宝回调异常：",e);
            return NotifyResult.unknowException();
        }
        if (verify_result) {
            AliNotifyResp notifyResponse = JSON.parseObject(JSON.toJSONString(params), AliNotifyResp.class);
            if (TradeStateEnum.TRADE_SUCCESS.getStatus().equals(notifyResponse.getTradeStatus())) {
                return NotifyResult.tradeSuccess(notifyResponse);
            } else {
                return NotifyResult.tradeSuccess(notifyResponse);
            }

        } else {
            //验证失败
            return NotifyResult.invalidSign();
        }
    }

    @Override
    public String success() {
        return "success";
    }

    @Override
    public String fail() {
        return "fail";
    }


    public static void main(String[] args) throws AlipayApiException {
        Map<String,String> params = Maps.newHashMap();
        params.put("gmt_create","2020-06-29 17:35:48");
        params.put("charset","utf-8");
        params.put("seller_email","3239434082@qq.com");
        params.put("subject","????"); //订单支付
        params.put("sign","TOKnEPtFBETjt+Bat8+DnohbxkE4SVU6KSqI9gxoN+V7Cs4nUYiyDmRa/XgfhPEMQsfYieqAYwNzTLGOuP1lgTI95BtuJZ2txcwvOzNCvONcx2RDyBE6jGHTSFT+dH8aWRFd5A8E9FAMLLDnTwwnmE9yGs5hT48VopNZisE/GsOC9nL/ktuqnzFFdzE5j6NrhJK1y2By/m1zyJMSEEJaRd+NwTjy31+0UyKumWm3AmDWO75NbEE3b8ROqdMWZvG0Ce8aDgJ2B1mx3Rghyk892PB73WKZwbHwz/vqJrhi91MZ6Qgk5yS/Svmq110kDBr9XKcWSKxmC/39YiJKWf3PiQ==");
        params.put("buyer_id","2088802168395392");
        params.put("invoice_amount","0.01");
        params.put("notify_id","2020062900222175929095391430858165");
        params.put("fund_bill_list","[{\"amount\":\"0.01\",\"fundChannel\":\"PCREDIT\"}]");
        params.put("notify_type","trade_status_sync");
        params.put("trade_status","TRADE_SUCCESS");
        params.put("receipt_amount","0.01");
        params.put("app_id","2016090301844463");
        params.put("buyer_pay_amount","0.01");
        params.put("sign_type","RSA2");
        params.put("seller_id","2088421791962869");
        params.put("gmt_payment","2020-06-29 17:59:28");
        params.put("notify_time","2020-06-29 17:59:29");
        params.put("version","1.0");
        params.put("out_trade_no","20200629173422200905");
        params.put("total_amount","0.01");
        params.put("trade_no","2020062922001495391420595868");
        params.put("auth_app_id","2016090301844463");
        params.put("buyer_logon_id","151****8605");
        params.put("point_amount","0.00");

        boolean rsa2 = AlipaySignature.rsaCheckV1(params, "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtRiifvWuY6Rz+7kMgy4w9YpNQzRkps7xr99APtNAWvf3wh2Xj6jOsQSSgowbzv9TglRQ0fVdoL6Rzpq4StnTEzrNsHcyQq2EVGZ6Q8IR6xs/9Iax5JjSOTm4mF9gqq4/y+ltLtMhfAu3YlmUx3vstJUz4v0CX1DjJZnwDBzHmRfH0YkQ8wh1wfaFx5E6dDQWioYI0bE5ycb+v4DmLw6ZcDWpWawRwGEowA3VnR1dcXlGgmA9f5BMYvLOZiLT5jyXmwYLhj7FkkwLrxHSRGg3yIIObXyuJg4Haz4xRd4xkxbo+1mb8d5zfnlsZhOxvtnSckQKpn2gEiN7is2yQX5jwQIDAQAB",
                "utf-8",
                "RSA2");
        System.out.println(rsa2);
    }
}
